home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / GENetReleaseƒ / GEBreakout / Breakout.c < prev   
C/C++ Source or Header  |  1994-03-07  |  11KB  |  552 lines

  1. /*
  2.     Breakout.c
  3.     
  4.     Breakout demo for Graphic Elements library
  5.     
  6.     3/7/94
  7.     
  8.     Al Evans
  9.     
  10.     Note: This is a fairly generic application shell.
  11.     The interesting parts are all in BGame.h and .c
  12. */
  13.  
  14. //Load precompiled symbol table if under MPW
  15. #ifdef applec
  16. #ifndef PRELOAD
  17. #pragma load "::ToolKit.precompile"
  18. #define PRELOAD
  19. #endif
  20. #else
  21. #include <QDOffscreen.h>
  22. #endif
  23.  
  24. #include <Timer.h>
  25. #include <GestaltEqu.h>
  26. #include "GUtilities.h"
  27. #include "GraphElements.h"
  28. #include "BGame.h"
  29.  
  30.  
  31. //define HISTOGRAM to collect times history
  32. #undef HISTOGRAM
  33.  
  34. #ifdef HISTOGRAM
  35. #include "StdIO.h"
  36. #endif
  37.  
  38.  
  39. //Menu Commands
  40.  
  41. #define    rMenuBar                128        /* application's menu bar */
  42.  
  43. #define    mApple                    128        /* Apple menu */
  44. #define    iAbout                    1
  45.  
  46. #define    mFile                    129        /* File menu */
  47. #define iNewGame                1
  48. #define    iQuit                    2
  49.  
  50. #define    mEdit                    130        /* Edit menu */
  51. #define    iUndo                    1
  52. #define    iCut                    3
  53. #define    iCopy                    4
  54. #define    iPaste                    5
  55. #define    iClear                    6
  56.  
  57. #define mSpecial                131
  58. #define iSingleFrame            1
  59.  
  60. #define    rAboutDialog            228        
  61.  
  62.  
  63. //Number of master pointer blocks needed
  64.  
  65. #define masterBlocksNeeded 10
  66.  
  67. //Globals
  68.  
  69. Boolean        gFinished;
  70. WindowPtr    gAnimWindow;
  71. Boolean        gSingleFrame = false;
  72. Boolean        gDoOne = false;
  73.  
  74. //Performance measurement
  75.  
  76. #define thirtySeconds 30L * 1000 * 1000        //µsec for timers -- never time out
  77.  
  78. TMTask    gTTimeTask, gATimeTask;
  79. unsigned long gTotalTime = 0, gAnimTime = 0;
  80.  
  81. #ifdef HISTOGRAM
  82. long    animTimes[100];
  83. long    mainTimes[100];
  84. #endif
  85.  
  86. //Forward declarations
  87.  
  88. #ifdef applec
  89. extern void _DataInit();    //reference so that we can unload it
  90. #endif
  91.  
  92. Boolean Initialize( void );
  93. void Shutdown(void);
  94. void EventLoop( void );
  95.  
  96. main()
  97. {
  98. #ifdef applec
  99.     UnloadSeg((Ptr) _DataInit);
  100. #endif
  101.     
  102.     MaxApplZone();
  103.     if ( Initialize() )
  104.         EventLoop();
  105.     Shutdown();
  106. }
  107.  
  108.  
  109. //Initialization
  110.  
  111. Boolean AdequateSystem(void)
  112. {
  113.     OSErr        err;
  114.     long        response;
  115.     Boolean        ok;
  116.     
  117.     //We need 68020 or better
  118.     err = Gestalt(gestaltProcessorType, &response);
  119.     ok = (!err) & (response >= gestalt68020);
  120.     
  121.     //We need System 7 or later
  122.     err = Gestalt(gestaltSystemVersion, &response);
  123.     ok = (!err) & (((response & 0xFFFF) / 256) >= 7);
  124.     
  125.     //We need color QD & offscreen GWorlds
  126.     err = Gestalt(gestaltQuickdrawVersion, &response);
  127.     ok = ok & (!err) & (response >= gestalt32BitQD);
  128.     err = Gestalt(gestaltQuickdrawFeatures, &response);
  129.     ok = ok & (!err) & (response >= 3);         //hasColor & deep GWorlds
  130.     
  131.     return ok;
  132.     
  133. }
  134.  
  135. //Make window centered on main graphic device
  136. WindowPtr MakeWindow(short wHSize, short wVSize)
  137. {
  138.     GDHandle    mainDevice;
  139.     Rect        devRect;
  140.     short        hOffst, vOffst;
  141.     Rect        windRect;
  142.     
  143.     mainDevice = GetMainDevice();
  144.     devRect = (**mainDevice).gdRect;
  145.     hOffst = (devRect.right - devRect.left - wHSize) / 2;
  146.     if (hOffst < 0) hOffst = 0;
  147.     vOffst = (devRect.bottom - devRect.top - wVSize) / 2;
  148.     if (vOffst < 0 ) vOffst = 0;
  149.     windRect.left = hOffst;
  150.     windRect.right = hOffst + wHSize;
  151.     windRect.top = vOffst;
  152.     windRect.bottom = vOffst + wVSize; 
  153.     
  154.     return NewCWindow(nil, &windRect, "\pGEBreakout", false, documentProc,
  155.                         (WindowPtr) -1L, false, 0L);
  156. }
  157.  
  158. void DoNothing( void )
  159. {
  160. }
  161.  
  162. void InitPerformanceTiming(void)
  163. {
  164.     //Init Timers
  165.     gTTimeTask.tmAddr = (TimerProcPtr) DoNothing;
  166.     gTTimeTask.tmWakeUp = 0;
  167.     gTTimeTask.tmReserved = 0;
  168.     
  169.     gATimeTask.tmAddr =  (TimerProcPtr) DoNothing;
  170.     gATimeTask.tmWakeUp = 0;
  171.     gATimeTask.tmReserved = 0;
  172.     
  173. }
  174.  
  175. Boolean Initialize(void)
  176. {
  177.     Rect        animRect;
  178.     GEWorldPtr    animWorld;
  179. #ifdef HISTOGRAM
  180.     short    count;
  181. #endif
  182.     
  183.     gFinished = false;
  184.     
  185.     InitSystem(masterBlocksNeeded);
  186.     
  187.     
  188.     if (!AdequateSystem()) {
  189.         TellUser("\pSorry, more powerful system required", 0);
  190.         return false;
  191.     }
  192.     if (!LoadMenus(rMenuBar)) {
  193.         TellUser("\pCould not load menus", 0);
  194.         return false;
  195.     }
  196.     
  197.     //DebugStr("\pInitializing...");
  198.     //Create window and install animation
  199.     if (gAnimWindow = MakeWindow(gWindWidth, gWindHeight)){
  200.         animRect.left = 0;
  201.         animRect.right = gWindWidth;
  202.         animRect.top = 0;
  203.         animRect.bottom = gWindHeight;
  204.         if (animWorld = NewGEWorld((CWindowPtr) gAnimWindow, &animRect, nil))
  205.             SetWRefCon(gAnimWindow, (long) animWorld);
  206.         else {
  207.             TellUser("\pCould not install animation in window", 0);
  208.             return false;
  209.         }
  210.     }
  211.     else {
  212.         TellUser("\pCould not create window", 0);
  213.         return false;
  214.     }
  215.     
  216.     InitPerformanceTiming();
  217.     qd.randSeed = TickCount();
  218.     
  219.     //Load game graphics
  220.     
  221.     if (!LoadBreakoutGame(animWorld)) {
  222.         TellUser("\pCould not load game graphics", 0);
  223.         return false;
  224.     }
  225.         
  226. #ifdef HISTOGRAM
  227.     for (count = 0; count < 100; count++) {
  228.         animTimes[count] = 0;
  229.         mainTimes[count] = 0;
  230.     }
  231. #endif
  232.  
  233.     
  234.     //Turn animation on and show window
  235.     ShowWindow(gAnimWindow);
  236.     ActivateWorld((GEWorldPtr) GetWRefCon(gAnimWindow), true);
  237.     return true;
  238.     
  239. }
  240.  
  241. #ifdef HISTOGRAM
  242. void DumpHistograms(void)
  243. {
  244.     short    count;
  245.     FILE*    dump;
  246.     
  247.     dump = fopen("HistoDump", "w");
  248.     for (count = 0; count < 100; count++) 
  249.         fprintf(dump, "%d\t%d\t%d\n", count, mainTimes[count], animTimes[count]);
  250.     fflush(dump);
  251.     fclose(dump);
  252. }
  253. #endif
  254.  
  255. void Shutdown(void)
  256. {
  257.     //Release system resources
  258.     
  259. #ifdef HISTOGRAM
  260.     DumpHistograms();
  261. #endif
  262.  
  263.     DisposeGEWorld((GEWorldPtr) GetWRefCon(gAnimWindow));
  264.     
  265.     ExitToShell();
  266. }
  267.  
  268.  
  269. #ifdef HISTOGRAM
  270. void DoHistogram(void)
  271. {
  272.     if ((gTotalTime - gAnimTime) < 100)
  273.         mainTimes[(gTotalTime - gAnimTime)]++;
  274.     else
  275.         mainTimes[99]++;
  276.     if (gAnimTime < 100)
  277.         animTimes[gAnimTime]++;
  278.     else
  279.         animTimes[99]++;
  280. }
  281. #endif
  282.  
  283. pascal Boolean AboutFilter(DialogPtr dialog, EventRecord *event, short *item)
  284. {
  285. #pragma unused (dialog)
  286.     DoWorldUpdate((GEWorldPtr) GetWRefCon(gAnimWindow), false);
  287.     if ((event->what == mouseDown) || (event->what == keyDown)) {
  288.         *item = ok;
  289.         return true;
  290.     }
  291.     else return false;
  292. }
  293.  
  294. void DoAboutBox(void)
  295. {
  296.     DialogPtr    aboutDialog;
  297.     short        itemHit;
  298.     
  299.     aboutDialog = GetNewDialog(rAboutDialog, nil, (WindowPtr) -1L);
  300.     ModalDialog(AboutFilter, &itemHit);
  301.     DisposDialog(aboutDialog);
  302. }
  303.  
  304.  
  305. //Event Handling
  306.  
  307. void EventLoop( void )
  308. {
  309.     Boolean        gotEvent;
  310.     EventRecord    event;
  311.     
  312.     void DoEvent (EventRecord *event);
  313.     void AdjustCursor( void);
  314.  
  315.     do {
  316.     
  317. #ifdef HISTOGRAM
  318.         InsTime( (QElemPtr) &gTTimeTask);
  319.         InsTime( (QElemPtr) &gATimeTask);
  320.         PrimeTime( (QElemPtr) &gTTimeTask, -thirtySeconds);
  321. #endif
  322.  
  323.         if (!gSingleFrame || gDoOne) {
  324.         
  325. #ifdef HISTOGRAM
  326.             PrimeTime( (QElemPtr) &gATimeTask, -thirtySeconds);
  327. #endif
  328.  
  329.             DoWorldUpdate((GEWorldPtr) GetWRefCon(gAnimWindow), false);
  330.             
  331. #ifdef HISTOGRAM
  332.             RmvTime( (QElemPtr) &gATimeTask);
  333.             gAnimTime = (thirtySeconds + gATimeTask.tmCount) / 1000;
  334. #endif
  335.  
  336.             gDoOne = false;
  337.         }
  338.         AdjustCursor();
  339.         if (gotEvent = WaitNextEvent(everyEvent, &event, 0L, nil)) 
  340.             DoEvent(&event);
  341.             
  342. #ifdef HISTOGRAM
  343.         RmvTime( (QElemPtr) &gTTimeTask);
  344.         gTotalTime = (thirtySeconds + gTTimeTask.tmCount) / 1000; //milliseconds
  345.         DoHistogram();
  346. #endif
  347.  
  348.     } while (!gFinished);
  349. }
  350.  
  351. void DoEvent (EventRecord *event)
  352. {
  353.     short        part;
  354.     WindowPtr    window;
  355.     char        key;
  356.     
  357.     //Prototypes
  358.     void AdjustMenus( void );
  359.     void DoMenuCommand(long menuResult);
  360.     void DoActivate(WindowPtr window, Boolean becomingActive);
  361.     void DoUpdate(WindowPtr window);
  362.     
  363.     switch ( event->what ) {
  364.         case mouseDown:
  365.             part = FindWindow(event->where, &window);
  366.             switch ( part ) {
  367.                 case inMenuBar:
  368.                     AdjustMenus();
  369.                     DoMenuCommand(MenuSelect(event->where));
  370.                     break;
  371.                 case inSysWindow:
  372.                     SystemClick(event, window);
  373.                     break;
  374.                 case inContent:
  375.                     if ( window != FrontWindow() ) 
  376.                         SelectWindow(window);
  377.                     if (MouseDownInSensor((GEWorldPtr) GetWRefCon(gAnimWindow), event->where))
  378.                         ;;
  379.                     break;
  380.                 case inDrag:
  381.                     DragWindow(window, event->where, &qd.screenBits.bounds);
  382.                     break;
  383.             }
  384.             break;
  385.         case keyDown:
  386.             key = event->message & charCodeMask;
  387.             if ( event->modifiers & cmdKey ) {
  388.                 AdjustMenus();
  389.                 DoMenuCommand(MenuKey(key));
  390.             }
  391.             else {
  392.                 switch (key) {
  393.                     case 'U':
  394.                     case 'u':
  395.                         MoveGEWorld((GEWorldPtr) GetWRefCon(gAnimWindow), 0, -50);
  396.                         break;
  397.                     case 'D':
  398.                     case 'd':
  399.                         MoveGEWorld((GEWorldPtr) GetWRefCon(gAnimWindow), 0, 50);
  400.                         break;
  401.                     case 'R':
  402.                     case 'r':
  403.                         MoveGEWorld((GEWorldPtr) GetWRefCon(gAnimWindow), 50, 0);
  404.                         break;
  405.                     case 'L':
  406.                     case 'l':
  407.                         MoveGEWorld((GEWorldPtr) GetWRefCon(gAnimWindow), -50, 0);
  408.                         break;
  409.                 }
  410.             }
  411.             gDoOne = true;
  412.             break;
  413.         case activateEvt:
  414.             DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
  415.             break;
  416.         case updateEvt:
  417.             DoUpdate((WindowPtr) event->message);
  418.             break;
  419.         case osEvt:
  420.             switch ((event->message >> 24) & 0x0FF) {
  421.                 case suspendResumeMessage:
  422.                     gInBackground = (event->message & resumeFlag) == 0;
  423.                     DoActivate(FrontWindow(), !gInBackground);
  424.                     break;
  425.             }
  426.             break;
  427.         }
  428. }
  429.  
  430. void DoActivate(WindowPtr window, Boolean becomingActive)
  431. {
  432. #pragma unused (window)
  433.     //Could start and stop animation here
  434.     ActivateWorld((GEWorldPtr) GetWRefCon(gAnimWindow), becomingActive);
  435. }
  436.  
  437.  
  438. void DoUpdate(WindowPtr window)
  439. {
  440.     Rect geRect;
  441.     GEWorldPtr geWorld;
  442.  
  443.     if (window == gAnimWindow)
  444.     {
  445.         SetPort( (GrafPtr) window );
  446.         //Protect GEWorld rect before updating window, since we will draw it
  447.         geWorld = (GEWorldPtr) GetWRefCon(gAnimWindow);
  448.         geRect = geWorld->animationRect;
  449.         RectOffset(&geRect, geWorld->worldFocus.h, geWorld->worldFocus.v);
  450.         ValidRect(&geRect);
  451.         
  452.         BeginUpdate(window);
  453.             FillRgn(((GrafPtr) window)->visRgn, qd.gray);
  454.         EndUpdate(window);
  455.         
  456.         DoWorldUpdate((GEWorldPtr) GetWRefCon(gAnimWindow), true);
  457.     }
  458. }
  459.  
  460. void AdjustMenus( void )
  461. {
  462.     WindowPtr    window;
  463.     MenuHandle    menu;
  464.     
  465.     window = FrontWindow();
  466.     
  467.     menu = GetMHandle(mFile);
  468.     EnableItem(menu, iNewGame);
  469.     EnableItem(menu, iQuit);
  470.  
  471.     menu = GetMHandle(mEdit);
  472.     if (window = gAnimWindow) {
  473.         DisableItem(menu, iUndo);
  474.         DisableItem(menu, iCut);
  475.         DisableItem(menu, iCopy);
  476.         DisableItem(menu, iClear);
  477.         DisableItem(menu, iPaste);
  478.     }
  479.     else {
  480.         EnableItem(menu, iUndo);
  481.         EnableItem(menu, iCut);
  482.         EnableItem(menu, iCopy);
  483.         EnableItem(menu, iClear);
  484.         EnableItem(menu, iPaste);
  485.     }
  486.     menu = GetMHandle(mSpecial);
  487.     //Set up special items!
  488.     CheckItem(menu, iSingleFrame, gSingleFrame);
  489. }
  490.  
  491. void DoMenuCommand(long menuResult)
  492. {
  493.     short        menuID;
  494.     short        menuItem;
  495.     Str255        daName;
  496.     short        daRefNum;
  497.  
  498.     menuID = HiWord(menuResult);
  499.     menuItem = LoWord(menuResult);
  500.     switch ( menuID ) {
  501.         case mApple:
  502.             switch ( menuItem ) {
  503.                 case iAbout:
  504.                     DoAboutBox();
  505.                     break;
  506.                 default:            /* all other items in this menu are DAs */
  507.                     GetItem(GetMHandle(mApple), menuItem, daName);
  508.                     daRefNum = OpenDeskAcc(daName);
  509.                     break;
  510.             }
  511.             break;
  512.         case mFile:
  513.             switch(menuItem) {
  514.                 case iNewGame:
  515.                     NewBreakoutGame((GEWorldPtr) GetWRefCon(gAnimWindow));
  516.                     ActivateWorld((GEWorldPtr) GetWRefCon(gAnimWindow), true);
  517.                     ShowWindow(gAnimWindow);
  518.                     break;
  519.                 case iQuit:
  520.                     gFinished = true;
  521.             }
  522.             break;
  523.         case mEdit:
  524.             (void) SystemEdit(menuItem-1);
  525.             break;
  526.         case mSpecial:
  527.             //Add special items
  528.             switch ( menuItem ) {
  529.                 case iSingleFrame:
  530.                     gSingleFrame = !gSingleFrame;
  531.                     break;
  532.             }
  533.             break;
  534.     }
  535.     HiliteMenu(0);
  536. }
  537.  
  538. //Utility routines
  539.  
  540.  
  541. void AdjustCursor( void )
  542. {
  543.     WindowPtr    window;
  544.     
  545.     window = FrontWindow();
  546.     
  547.     if ( (window == gAnimWindow) && (!gInBackground) ) {
  548.         SetCursor(&qd.arrow);
  549.     }
  550. }
  551.  
  552.